#ifndef _StreamableGeometry_h__
#define _StreamableGeometry_h__

#include <buildspec.h>
#include <config.h>
#include <Geometry/IGeometry.h>
#include <Geometry/SRS.h>
#include <Geometry/IFileSerialisable.h>
#include <boost/shared_ptr.hpp>

namespace GST {
namespace Geometry {

	/**
	  * This interface is used by ClientUtils::NetworkInterface to serialize the geometry, possibly back 
	  * and send to the database.
	  *
	  * You can overload the methods producing the output direct form your geometry.
	  *
	  * If you want to stay away from generating output, it is recommenced to use the GeometryBuilder and
	  * represent your geometry including properties there. It will produce the output for you.
	  *
	  * @see GeometryBuilder
	  */
class GST_API_EXPORT StreamableGeometry
{
public:

	typedef std::vector< std::pair<std::string, std::string> > KeyValueList;
	typedef boost::shared_ptr<KeyValueList> KeyValueListPtr;
	
	/** 
	  * Writes the geometry the an output stream. It's allowed to produce any output that can be read by GST Storage.
	  * The most easy format is WKT (well known text) of the Simple Feature Standard from OGC (http://www.opengeospatial.org/standards/sfs)
	  *
	  * A Parser reading this format is included in include_wktGrammar.h.
	  * You can test your output against this Parser using the following code.
	  \code
	  std::stringstream output_geometry;
	  gb.serializeGeometry(output_geometry);
	  boost::shared_ptr<GeometryBuilder> constructed_Geometry = boost::make_shared<GeometryBuilder>();
	  try{
		parseGeometry(constructed_Geometry,output_geometry.str());
		//good
	  }catch(const std::exception& e){ 
		//bad
	  }
	  \endcode
	  *		  
	  * If you want to stay away from generating output, it is recommenced to use the GeometryBuilder and
	  * represent your geometry including properties there. It will produce the output for you.
	  *
	  * @see GeometryBuilder
	  */
	virtual bool serializeGeometry(std::ostream & os) const = 0;

	/**
	  * If you want to stay away from generating output, it is recommenced to use the GeometryBuilder and
	  * represent your geometry including properties there. It will produce the output for you.
	  *
	  * @see GeometryBuilder 
	  */
	virtual bool serializeSimplexPropertyValues(std::ostream & os) const = 0;

	/**
	  * If you want to stay away from generating output, it is recommenced to use the GeometryBuilder and
	  * represent your geometry including properties there. It will produce the output for you.
	  *
	  * @see GeometryBuilder 
	  */
	virtual bool serializeSimplexPropertyDescription(std::ostream & os) const = 0;

	virtual std::string GetName() const = 0;
	virtual IGeometry::Color GetColor() const = 0; 
	virtual IGeometry::TransparencyCode GetTransparency() const = 0;
	virtual Geometry::SRSPtr GetSRS() const = 0;
	virtual KeyValueListPtr GetVariousProperties() const = 0;

protected:
	virtual std::string constructSendHeader(IFileSerialisable::FileType ftype, const int & size) const
	{
		std::stringstream sendingheader;

		sendingheader << "{";//json doc start
		sendingheader << "\"items\":[";//main array

		WriteJsonHeaderPart( sendingheader, ftype, size );

		sendingheader << "]";//main array
		sendingheader << "}";//json doc end

		return sendingheader.str();
	}
	virtual void WriteJsonHeaderPart( std::stringstream & sendingheader, IFileSerialisable::FileType ftype, const int & size ) const
	{
		sendingheader << "{\"type\":\"" << IFileSerialisable::FileType2JsonSendingType( ftype ) << "\",";
		sendingheader << "\"size\":" << size << "}";
	}
};	

} //namespace Geometry
} //namespace GST

#endif // _StreamableGeometry_h__